<template>
  <div class="camera-view">
    <card>
      <div class="camera-content h-full flex">
        <!-- 左侧文件夹树 -->
        <div class="left-panel w-80 flex-shrink-0 border-r border-gray-200 pr-4">
          <div class="tree-header mb-4">
            <h3 class="text-lg font-medium text-gray-700">设备目录</h3>
          </div>
          
          <div class="tree-container h-full overflow-auto">
            <el-tree
              v-if="menuTree.length > 0"
              :data="menuTree"
              :props="treeProps"
              node-key="id"
              :default-expand-all="false"
              :default-expanded-keys="defaultExpandedKeys"
              :current-node-key="selectedNode?.id"
              :highlight-current="true"
              @node-click="handleNodeClick"
              class="menu-tree"
            >
              <template #default="{ data }">
                <div class="tree-node flex items-center">
                  <el-icon class="mr-2">
                    <Folder />
                  </el-icon>
                  <span class="node-label">{{ data.name }}</span>
                </div>
              </template>
            </el-tree>
            
            <div v-else-if="loading" class="loading-container flex items-center justify-center h-32">
              <el-icon class="is-loading text-2xl text-blue-500">
                <Loading />
              </el-icon>
              <span class="ml-2 text-gray-500">加载中...</span>
            </div>
            
            <div v-else class="empty-container flex items-center justify-center h-32 text-gray-500">
              <span>暂无数据</span>
            </div>
          </div>
        </div>

        <!-- 右侧摄像头列表 -->
        <div class="right-panel flex-1 pl-4 flex flex-col">
          <div class="list-header mb-4 flex items-center justify-between">
            <h3 class="text-lg font-medium text-gray-700">
              {{ selectedNode ? `摄像头列表 - ${selectedNode.name}` : '请选择设备目录' }}
            </h3>
            
            <!-- 搜索框 -->
            <div class="search-box" v-if="selectedNode">
              <el-input
                v-model="searchKeyword"
                placeholder="搜索摄像头..."
                clearable
                @change="handleSearch"
                @clear="handleSearch"
                class="w-64"
              >
                <template #prefix>
                  <el-icon>
                    <Search />
                  </el-icon>
                </template>
              </el-input>
            </div>
          </div>

          <!-- 摄像头列表 -->
          <div class="list-container flex-1" v-if="selectedNode">
            <ElementTable
              :tableTitle="tableColumns"
              :data="cameraList"
              :showPagination="true"
              :pageConfig="pageConfig"
              :itemType="'摄像机'"
              :delMethod="handleDeleteCamera"
              :refreshMethod="loadCameraList"
              @selectChange="handleSelectionChange"
              class="camera-table"
            >
              <template #location="{ data }">
                <el-link 
                  :type="data.row.latitude && data.row.longitude ? 'success' : 'info'"
                  :underline="true"
                  @click="handleLocationClick(data.row)"
                >
                  {{ data.row.latitude && data.row.longitude ? '已标记' : '未标记' }}
                </el-link>
              </template>
          </ElementTable>
          </div>
          
          <div v-else class="empty-list flex items-center justify-center h-64 text-gray-500">
            <div class="text-center">
              <el-icon class="text-4xl mb-2">
                <Camera />
              </el-icon>
              <p>请从左侧选择设备目录查看摄像头列表</p>
            </div>
          </div>
        </div>
      </div>
    </card>

    <!-- 流播放对话框 -->
    <StreamPlayerDialog 
      :visible="streamPlayerVisible" 
      :camera-data="currentCameraData" 
      :server-data="currentServerData"
      @close="handleCloseStreamPlayer" 
      @update:visible="streamPlayerVisible = $event" 
    />

    <!-- 修改设备名字对话框 -->
    <EditCameraNameDialog
      :visible="editCameraNameVisible"
      :camera-data="currentEditCamera"
      @close="handleCloseEditCameraName"
      @success="handleEditCameraNameSuccess"
      @update:visible="editCameraNameVisible = $event"
    />

    <!-- 设备位置标记对话框 -->
    <CameraLocationDialog
      :visible="locationDialogVisible"
      :camera-data="currentLocationCamera"
      @close="handleCloseLocationDialog"
      @save="handleSaveLocation"
      @update:visible="locationDialogVisible = $event"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { Folder, Loading, Search, Camera } from '@element-plus/icons-vue'
import ElementTable from '@/components/ElementTable/index.vue'
import StreamPlayerDialog from '@/views/device/stream/components/StreamPlayerDialog.vue'
import EditCameraNameDialog from './components/EditCameraNameDialog.vue'
import CameraLocationDialog from './components/CameraLocationDialog.vue'
import { buildTree } from '@/utils/tree'
import request from '@/utils/request'
import { useStreamStore } from '@/stores/stream'
import { warning, error } from '@/utils/toast'
import type { TreeNode, Device, StreamServer } from '@/types'
import { getCameraTree } from '@/api/camera'
import { $getDeviceListByKeyword } from '@/api/device'

// 使用store
const streamStore = useStreamStore()

// 响应式数据
const loading = ref(false)
const menuTree = ref<TreeNode[]>([])
const selectedNode = ref<TreeNode | null>(null)
const cameraList = ref<any[]>([])
const searchKeyword = ref('')
const selectedCameras = ref<any[]>([])
const defaultExpandedKeys = ref<number[]>([])

// 播放相关数据
const streamPlayerVisible = ref(false)
const currentCameraData = ref<Device | null>(null)
const currentServerData = ref<StreamServer | null>(null)

// 修改设备名字相关数据
const editCameraNameVisible = ref(false)
const currentEditCamera = ref<{ id: number; name: string } | null>(null)

// 设备位置标记相关数据
const locationDialogVisible = ref(false)
const currentLocationCamera = ref<Device | null>(null)

// 树形组件配置
const treeProps = {
  children: 'children',
  label: 'name'
}

// 分页配置
const pageConfig = reactive({
  currentPage: 1,
  pageSize: 20,
  pageSizes: [10, 20, 50, 100],
  layout: 'total, sizes, prev, pager, next, jumper',
  total: 0,
  background: true,
  handleSizeChange: (size: number) => {
    pageConfig.pageSize = size
    pageConfig.currentPage = 1
    loadCameraList()
  },
  handleCurrentChange: (page: number) => {
    pageConfig.currentPage = page
    loadCameraList()
  }
})

// 表格列配置
const tableColumns = [
  {
    type: 'selection',
    width: '50'
  },
  {
    type: 'index',
    label: '序号',
    width: '80'
  },
  {
    type: 'text',
    label: '设备名称',
    prop: 'name',
  },
  {
    type: 'text',
    label: '摄像机ID',
    prop: 'id',
  },
  {
    type: 'status',
    label: '摄像机位置',
    prop: 'posionType',
    options: [
      { value: '1', text: '室外', type: 'success' },
      { value: '2', text: '室内', type: 'danger' }
    ]
  },
  {
    type: 'text',
    label: 'IP',
    prop: 'ip',
    showOverflowTooltip: true
  },
  {
    type: 'text',
    label: '端口',
    prop: 'port',
    width: '80'
  },
  {
    type: 'status',
    label: '状态',
    prop: 'status',
    width: '100',
    options: [
      { value: 1, text: '在线', type: 'success' },
      { value: 0, text: '离线', type: 'danger' }
    ]
  },
  {
    type: 'custom',
    label: '地图标记',
    name: 'location',
    width: '120'
  },
  {
    type: 'operate',
    label: '操作',
    width: '200',
    actions: [
      {
        name: '播放',
        type: 'primary',
        size: 'small',
        isLink: true,
        click: (row: any) => {
          handlePlayCamera(row)
        }
      },
      {
        name: '修改',
        type: 'primary',
        size: 'small',
        isLink: true,
        click: (row: any) => {
          handleEditCamera(row)
        }
      },
    ]
  }
]

// 加载菜单树
const loadMenuTree = async () => {
  try {
    loading.value = true
    const response = await getCameraTree()
    if (response.data && Array.isArray(response.data)) {
      // 使用项目中的树形数据转换方法
      menuTree.value = buildTree(response.data)
      // 默认选中第一个根节点
      if (menuTree.value.length > 0) {
        selectedNode.value = menuTree.value[0]
        // 设置默认展开的节点（根节点）
        defaultExpandedKeys.value = [menuTree.value[0].id]
        // 加载默认选中节点的摄像头列表
        loadCameraList()
      }
    }
  } finally {
    loading.value = false
  }
}

// 加载摄像头列表
const loadCameraList = async () => {
  if (!selectedNode.value?.id) return
  
  try {
    loading.value = true
    const response = await request.post('/deviceController/getDeviceListByPage', {
      page: pageConfig.currentPage,
      pageSize: pageConfig.pageSize,
      keyWord: searchKeyword.value,
      menuId: selectedNode.value.id,
      isContainsSubMenu: true
    })
    
    if (response.data && typeof response.data === 'object') {
      cameraList.value = response.data.data || []
      pageConfig.total = response.data.total || 0
    }
  }  finally {
    loading.value = false
  }
}

// 处理树节点点击
const handleNodeClick = (data: TreeNode) => {
  selectedNode.value = data
  pageConfig.currentPage = 1
  searchKeyword.value = ''
  loadCameraList()
}

// 处理搜索
const handleSearch = async () => {
  if (!searchKeyword.value.trim()) {
    // 如果搜索关键词为空，重新加载当前目录的设备列表
    loadCameraList()
    return
  }
  
  try {
    loading.value = true
    const response = await $getDeviceListByKeyword(searchKeyword.value.trim())
    
    if (response.data && Array.isArray(response.data)) {
      cameraList.value = response.data
      pageConfig.total = response.data.length
      pageConfig.currentPage = 1
    } else {
      cameraList.value = []
      pageConfig.total = 0
    }
  } catch (err: any) {
    console.error('搜索设备失败:', err)
    error('搜索设备失败，请重试')
    cameraList.value = []
    pageConfig.total = 0
  } finally {
    loading.value = false
  }
}

// 处理选择变化
const handleSelectionChange = (selection: any[]) => {
  selectedCameras.value = selection
}

// 修改摄像头
const handleEditCamera = (camera: any) => {
  // 设置当前编辑的摄像头数据
  currentEditCamera.value = {
    id: camera.id,
    name: camera.name
  }
  // 显示修改弹框
  editCameraNameVisible.value = true
}

// 删除摄像头
const handleDeleteCamera = (_camera: any) => {
  // TODO: 实现删除摄像头逻辑
}

// 播放摄像头
const handlePlayCamera = (camera: any) => {
  // 确保流媒体服务器数据已加载
  if (streamStore.streamServers.length === 0) {
    warning('流媒体服务器数据未加载，请稍后重试')
    return
  }
  
  // 查找对应的流媒体服务器
  const server = streamStore.streamServers.find(server => server.id === camera.nvrId)
  if (!server) {
    error('未找到对应的流媒体服务器')
    return
  }
  
  // 设置当前播放的摄像头和服务器数据
  currentCameraData.value = camera
  currentServerData.value = server
  streamPlayerVisible.value = true
}

// 关闭播放弹框
const handleCloseStreamPlayer = () => {
  streamPlayerVisible.value = false
  currentCameraData.value = null
  currentServerData.value = null
}

// 关闭修改设备名字弹框
const handleCloseEditCameraName = () => {
  editCameraNameVisible.value = false
  currentEditCamera.value = null
}

// 处理修改设备名字成功
const handleEditCameraNameSuccess = (cameraId: number, newName: string) => {
  // 更新列表中的设备名字
  const camera = cameraList.value.find(cam => cam.id === cameraId)
  if (camera) {
    camera.name = newName
  }
  
  // 关闭弹框
  handleCloseEditCameraName()
}

// 处理位置标记点击
const handleLocationClick = (camera: Device) => {
  // 检查设备位置类型
  if (camera.posionType === 0) {
    // 室内设备，显示提醒
    warning('该设备是室内设备，无需进行位置标记')
    return
  }
  
  // 室外设备，打开位置标记对话框
  currentLocationCamera.value = camera
  locationDialogVisible.value = true
}

// 关闭位置标记对话框
const handleCloseLocationDialog = () => {
  locationDialogVisible.value = false
  currentLocationCamera.value = null
}

// 保存位置标记
const handleSaveLocation = async (data: { id: number; longitude: string; latitude: string }) => {
  try {
    // 这里调用API保存位置信息
    // await request.post('/deviceController/updateDeviceLocation', {
    //   deviceId: data.id,
    //   longitude: data.longitude,
    //   latitude: data.latitude
    // })
    
    // 更新列表中的位置信息
    const camera = cameraList.value.find(cam => cam.id === data.id)
    if (camera) {
      camera.longitude = data.longitude
      camera.latitude = data.latitude
    }
    
    // 关闭对话框
    handleCloseLocationDialog()
  } catch (err) {
    console.error('保存位置信息失败:', err)
    error('保存位置信息失败，请重试')
  }
}

// 组件挂载时加载数据
onMounted(async () => {
  // 加载流媒体服务器数据
  await streamStore.loadStreamServers()
  // 加载菜单树
  loadMenuTree()
})
</script>

<style scoped lang="scss">
.camera-view {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.camera-content {
  min-height: 600px;
}

.left-panel {
  .tree-header {
    border-bottom: 1px solid #e5e7eb;
    padding-bottom: 12px;
  }
  
  .tree-container {
    max-height: calc(100vh - 200px);
  }
}

.right-panel {
  .list-header {
    border-bottom: 1px solid #e5e7eb;
    padding-bottom: 12px;
  }
  
  .list-container {
    min-height: 400px;
    overflow: hidden;
  }
}

.tree-node {
  padding: 4px 0;
  
  .node-label {
    font-size: 14px;
    color: #374151;
  }
}

.menu-tree {
  :deep(.el-tree-node__content) {
    height: 36px;
    border-radius: 4px;
    margin: 2px 0;
    
    &:hover {
      background-color: #f3f4f6;
    }
  }
  
  :deep(.el-tree-node.is-current > .el-tree-node__content) {
    background-color: #dbeafe !important;
    color: #1d4ed8 !important;
    font-weight: 500;
  }
  
  :deep(.el-tree-node.is-current > .el-tree-node__content:hover) {
    background-color: #bfdbfe !important;
  }
}

.empty-container,
.empty-list {
  background-color: #f9fafb;
  border: 1px dashed #d1d5db;
  border-radius: 8px;
}

.loading-container {
  background-color: #f9fafb;
  border-radius: 8px;
}

.camera-table {
  height: 100%;
}
</style>